#pragma once

#include "Context.h"
#include "Views/ViewManager.h"
#include "File/ShaderLoader.h"
#include "File/TextureLoader.h"

#include <memory>
#include <string>
#include <functional>

class Kernel; typedef std::shared_ptr<Kernel> KernelPtr;
class Kernel
{
public:
	static KernelPtr getSingleton();
	static void Shutdown();
	~Kernel();

	void config(const std::string &resource_dir);
	bool init(int argc, char** argv);

	void run();
	void exit() { running = false; }
	bool isRunning() const { return running; }

	void update(float time);
	void render();
	void reshape(int w, int h);

public:
	void destroyContextUsers();
	const std::string &getResourceDir() const { return resource_dir; }

private:
#if(_MSC_VER >= 1700)
	friend class std::_Ref_count_obj<Kernel>;
#else
	friend class std::tr1::_Ref_count_obj<Kernel>;
#endif
	static KernelPtr singleton;
	Kernel();

	void keyInput(int key, int pressed);
	void mouseButtonInput(int button, int pressed);
	void mouseMoveInput(int x, int y);

	std::string resource_dir;
	bool running;
	double previous_time;

	std::unique_ptr<GLContext> context;
	std::unique_ptr<Views::ViewManager> view_manager;

	File::ShaderLoaderPtr shader_loader;
	File::TextureLoaderPtr tex_loader;
};
